package com.ruoyi.wechat.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.wechat.config.TaskExcutor;
import com.ruoyi.wechat.domain.TemplateMsgBatchForm;
import com.ruoyi.wechat.domain.TemplateMsgLog;
import com.ruoyi.wechat.domain.WxUser;
import com.ruoyi.wechat.service.MsgTemplateService;
import com.ruoyi.wechat.service.TemplateMsgLogService;
import com.ruoyi.wechat.service.TemplateMsgService;
import com.ruoyi.wechat.service.WxUserService;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yan
 * @date  2022-07-18
 */
@Service
@RequiredArgsConstructor
public class TemplateMsgServiceImpl implements TemplateMsgService {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    @Resource
    private TemplateMsgLogService templateMsgLogService;
    private final WxMpService wxService;
    @Autowired
    MsgTemplateService msgTemplateService;
    @Resource
    WxUserService wxUserService;

    /**
     * 发送微信模版消息,使用固定线程的线程池
     */
    @Override
    @Async
    public void sendTemplateMsg(WxMpTemplateMessage msg, String appid) {
        TaskExcutor.submit(() -> {
            String result;
            try {
                wxService.switchover(appid);
                result = wxService.getTemplateMsgService().sendTemplateMsg(msg);
            } catch (WxErrorException e) {
                result = e.getMessage();
            }

            //保存发送日志
            TemplateMsgLog log = new TemplateMsgLog(msg, appid, result);
            templateMsgLogService.addLog(log);
        });
    }

    @Override
    @Async
    public void sendMsgBatch(TemplateMsgBatchForm form, String appid) {
        logger.info("批量发送模板消息任务开始,参数：{}", form.toString());
        wxService.switchover(appid);
        WxMpTemplateMessage.WxMpTemplateMessageBuilder builder = WxMpTemplateMessage.builder()
                .templateId(form.getTemplateId())
                .url(form.getUrl())
                .miniProgram(form.getMiniprogram())
                .data(form.getData());
        Map<String, Object> filterParams = form.getWxUserFilterParams();
        logger.info("消息模板map值:{}", filterParams);
        if (filterParams == null) {
            filterParams = new HashMap<>(8);
        }
        filterParams.put("tagid_list", filterParams.get("tagId").toString());
        long currentPage = 1L, totalPages = Long.MAX_VALUE;
        filterParams.put("appid", appid);
        filterParams.put("limit", "500");
        while (currentPage <= totalPages) {
            filterParams.put("page", String.valueOf(currentPage));
            //按条件查询用户
            String tagId = filterParams.get("tagId").toString();
            WxUser wxUser = new WxUser();
            Wrapper<WxUser> wxUsers;
            if (StringUtils.isNotBlank(tagId)) {
                wxUsers = Wrappers.lambdaQuery(wxUser)
                        .eq(WxUser::getAppid, appid)
                        .and(wrapper -> wrapper
                                .eq(WxUser::getTagidList, "[" + tagId + "]")
                                .or()
                                .like(WxUser::getTagidList, "," + tagId + ",")
                                .or()
                                .likeRight(WxUser::getTagidList, "[" + tagId + ",")
                                .or()
                                .likeLeft(WxUser::getTagidList, "," + tagId + "]"));
            } else if (StrUtil.isNotBlank(wxUser.getNickname())) {
                String nickName = wxUser.getNickname();
                wxUser.setNickname(null);
                wxUsers = Wrappers.lambdaQuery(wxUser)
                        .eq(WxUser::getAppid, appid)
                        .like(WxUser::getNickname, nickName);
            } else if (StrUtil.isNotBlank(wxUser.getRemark())) {
                String remark = wxUser.getRemark();
                wxUser.setRemark(null);
                wxUsers = Wrappers.lambdaQuery(wxUser)
                        .eq(WxUser::getAppid, appid)
                        .like(WxUser::getRemark, remark);
            } else {
                wxUsers = Wrappers.lambdaQuery(wxUser).eq(WxUser::getAppid, appid);
            }
            Page page = new Page();
            page.setCurrent(currentPage);
            IPage<WxUser> wxUserList = wxUserService.page(page, wxUsers);

            logger.info("批量发送模板消息任务,使用查询条件，处理第{}页，总用户数：{}", currentPage, wxUserList.getTotal());
            wxUserList.getRecords().forEach(user -> {
                WxMpTemplateMessage msg = builder.toUser(user.getOpenid()).build();
                this.sendTemplateMsg(msg, appid);
            });
            currentPage = wxUserList.getCurrent() + 1L;
            totalPages = wxUserList.getPages();
        }
        logger.info("批量发送模板消息任务结束");

    }


}
